/*
 * Copyright (C) 2009 Rafael Fernandes
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phonebooksharing.android.activities.main;

import java.util.ArrayList;

import android.app.ExpandableListActivity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.phonebooksharing.android.R;
import com.phonebooksharing.android.activities.dashboard.DashboardReader;
import com.phonebooksharing.android.activities.image.ImageGallerySharingContainer;
import com.phonebooksharing.android.activities.pref.PreferencesActivity;
import com.phonebooksharing.android.activities.video.VideoGallerySharingContainer;
import com.phonebooksharing.android.async.DashboardUpdaterTask;
import com.phonebooksharing.android.provider.PhonebookSharingManager;
import com.phonebooksharing.android.provider.PhonebookSharing.Dashboard;
import com.phonebooksharing.android.provider.PhonebookSharing.Sync;
import com.phonebooksharing.android.util.CloseableUtil;

public class DashboardActivity extends ExpandableListActivity {
    private TextView emptyText;
    private ProgressBar emptyPG;
    private AsyncTask<?, ?, ?> task;
    
    private static final int QTY_FRIENDS_NEARBY = 0,
                             QTY_MESSAGES = 1,
                             QTY_POSTCARDS = 2,
                             QTY_PLACES_NEARBY = 3,
                             QTY_PHOTOS = 4,
                             QTY_VIDEOS = 5,
                             QTY_JOURNAL = 6,
                             QTY_NON_SHARING_IMAGES = 7,
                             QTY_NON_SHARING_VIDEOS = 8;
    
    private DashboardExpandableAdapter m_adapter;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setBackgroundDrawable(null);
        setContentView(R.layout.list_layout_expand_with_empty);
        getExpandableListView().setDivider(getResources().getDrawable(R.drawable.black_bar));
        
        buildDashboard();
        
        new CleanSyncInfo().execute();
    }

    private void buildDashboard() {
        ArrayList<Group> groups = new ArrayList<Group>();
        
        addNearby(groups);
        addInbox(groups);
        addNotShareable(groups);

        final ArrayList<Sync> sl = PhonebookSharingManager.getSyncList(getContentResolver(), Sync.SYNC_TYPE + " = 0");
        Group gs = new Group("Sync Info", new ArrayList<Child>(), sl.size());
        Child ch;
        for(Sync s : sl) {
            ch = new Child();

            //TODO: add icons accordingly
//            switch (s.getSyncStatus()) {
//                case Sync.STATUS_NOT_COMPLETED:
//                    ch.icon  = R.drawable.dash_last_sync_info;
//                    break;
//                default:
//                    break;
//            }
            
            ch.icon  = R.drawable.dash_last_sync_info;
            ch.desc = s.syncAddress;
            ch.small = "" + DateUtils.getRelativeTimeSpanString(s.syncTime, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE);
            ch.title = s.getSyncStatusDesc();
            gs.childs.add(ch);
        }
        if(gs.childs.size() > 0) groups.add(gs);

        m_adapter = null;
        m_adapter = new DashboardExpandableAdapter(this, groups);
        setListAdapter(m_adapter);
        
        ExpandableListView elv = getExpandableListView();
        int i = 0;
        for(Group g : groups) {
            if(g.expand) elv.expandGroup(i);
            i++;
        }
    }

    private Dashboard dashboard;
    private void addNearby(ArrayList<Group> groups) {
        dashboard = PhonebookSharingManager.getDashboard(getContentResolver(), Dashboard.CONTENT_URI);
        final ArrayList<Child> child = new ArrayList<Child>();
        int i, count = 0;
        if ((i = dashboard.qtyFriendsNearby) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_friends_nearby;
            ch.title = "Friends Nearby";
            ch.small = "(" + i + " items)";
            ch.desc = "You've got friends nearby";
            ch.what = QTY_FRIENDS_NEARBY;

            count += i;
            child.add(ch);
        }

        if ((i = dashboard.qtyPlacesNearby) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_places_nearby;
            ch.title = "Places Nearby";
            ch.small = "(" + i + " items)";
            ch.desc = "You've got places nearby";
            ch.what = QTY_PLACES_NEARBY;

            count += i;
            child.add(ch);
        }
        groups.add(new Group("Nearby", child, count));
    }

    private void addInbox(ArrayList<Group> groups) {
        final ArrayList<Child> child = new ArrayList<Child>();
        int i, count = 0;
        
        //nearby 
        if ((i = dashboard.qtyMessages) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_messages;
            ch.title = "Unread messages";
            ch.small = "(" + i + " items)";
            ch.desc = "You've got messages";
            ch.what = QTY_MESSAGES;

            count += i;
            child.add(ch);
        }

        if ((i = dashboard.qtyPostcards) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_post_card;
            ch.title = "Unread postcards";
            ch.small = "(" + i + " items)";
            ch.desc = "You've got postcards";
            ch.what = QTY_POSTCARDS;

            count += i;
            child.add(ch);
        }

        if ((i = dashboard.qtyPhotos) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_photos;
            ch.title = "Unseen photos";
            ch.small = "(" + i + " items)";
            ch.desc = "You've got photos";
            ch.what = QTY_PHOTOS;

            count += i;
            child.add(ch);
        }
        
        if ((i = dashboard.qtyVideos) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_videos;
            ch.title = "Unseen Videos";
            ch.small = "(" + i + " items)";
            ch.desc = "You've got new videos";
            ch.what = QTY_VIDEOS;

            count += i;
            child.add(ch);
        }

        if ((i = dashboard.qtyJournal) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_friends_activities;
            ch.title = "Friend activities";
            ch.small = "(" + i + " items)";
            ch.desc = "Your friends activites";
            ch.what = QTY_JOURNAL;

            count += i;
            child.add(ch);
        }

        Group inbox = new Group("My Inbox", child, count);
        inbox.expand = true;
        groups.add(inbox);
    }
    
    private void addNotShareable(ArrayList<Group> groups) {
        final ArrayList<Child> child = new ArrayList<Child>();
        int i, count = 0;
        if ((i = dashboard.qtyNonSharingImages) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_photos;
            ch.title = "Images";
            ch.small = "(" + i + " items)";
            ch.desc = "You aren't sharing these images";
            ch.what = QTY_NON_SHARING_IMAGES;

            count += i;
            child.add(ch);
        }
        if ((i = dashboard.qtyNonSharingVideos) > 0) {
            Child ch = new Child();
            ch.icon = R.drawable.dash_videos;
            ch.title = "Videos";
            ch.small = "(" + i + " items)";
            ch.desc = "You aren't sharing these videos";
            ch.what = QTY_NON_SHARING_VIDEOS;

            count += i;
            child.add(ch);
        }
        groups.add(new Group("Not yet Sharing", child, count));
    }
    
    static class Group {
        Group(String n, ArrayList<Child> childs, long count) {
            this.name = n;
            this.count = count;
            this.childs = childs;  
        }
        boolean expand; //TODO: make me a preference
        String name;
        long count;
        ArrayList<Child> childs;
    }
    
    static class Child {
        int icon, what;
        String title, small, desc;
    }
    
    static class DashboardExpandableAdapter extends BaseExpandableListAdapter {
        private ArrayList<Group> groups;
        private LayoutInflater inflater;

        public DashboardExpandableAdapter(Context c, ArrayList<Group> groups) {
            this.groups = groups;
            this.inflater = LayoutInflater.from(c);
        }

        @Override
        public Object getChild(int gp, int cp) {
            return groups.get(gp).childs.get(cp);
        }

        @Override
        public long getChildId(int gp, int cp) {
            return groups.get(gp).childs.get(cp).what;
        }

        @Override
        public View getChildView(int gp, int cp, boolean isLastChild, View cv, ViewGroup parent) {
            ViewHolder holder;
            
            Group g = groups.get(gp);
            Child c = g.childs.get(cp);
            if(cv == null) {
                cv = inflater.inflate(R.layout.list_item_3lines, parent, false);
                holder = new ViewHolder();
                holder.icon = (ImageView)cv.findViewById(android.R.id.icon);
                holder.text1 = (TextView)cv.findViewById(android.R.id.text1);
                holder.text2 = (TextView)cv.findViewById(R.id.text2);
                holder.text3 = (TextView)cv.findViewById(R.id.text3);

                cv.setTag(holder);
            } else {
                holder = (ViewHolder)cv.getTag();
            }
            
            holder.icon.setImageResource(c.icon);
            holder.text1.setText(c.title);
            holder.text2.setText(c.small);
            holder.text3.setText(c.desc);
            
            return cv;
        }

        @Override
        public int getChildrenCount(int gp) {
            if( gp >= groups.size()){
                return 0;
            }
            return groups.get(gp).childs.size();
        }

        @Override
        public Object getGroup(int gp) {
            return groups.get(gp);
        }

        @Override
        public int getGroupCount() {
            return groups.size();
        }

        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            Group g = groups.get(groupPosition);
            View rv;
            if (convertView == null) {
                rv = inflater.inflate(R.layout.exp_2column, null);
            } else {
                rv = convertView;
            }
            ((TextView) rv.findViewById(android.R.id.text1)).setText(g.name);
//            if(g.count > 0) {
                ((TextView) rv.findViewById(android.R.id.text2)).setText("(" + g.count + " items)");
//            }
            return rv;
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
        
        static class ViewHolder {
        	ImageView icon;
        	TextView text1, text2, text3;
        }
    }
    
    @Override
    public boolean onChildClick(ExpandableListView parent, View v, int gp, int cp, long id) {
        if(gp < 2) {//nearby and inbox
            int factor = 1;
            switch ((int)id) {
                case QTY_FRIENDS_NEARBY:
                    factor--;
                case QTY_MESSAGES:
                case QTY_POSTCARDS: 
                case QTY_PLACES_NEARBY: 
                case QTY_PHOTOS: 
                case QTY_VIDEOS:
                case QTY_JOURNAL: {
                    Intent i = new Intent(this, DashboardReader.class);
                    i.putExtra(DashboardReader.QTY_FRIENDS_NEARBY, dashboard.qtyFriendsNearby);
                    i.putExtra(DashboardReader.QTY_PLACES_NEARBY,  dashboard.qtyPlacesNearby);
                    i.putExtra(DashboardReader.QTY_MESSAGES,       dashboard.qtyMessages);
                    i.putExtra(DashboardReader.QTY_POSTCARDS,      dashboard.qtyPostcards);
                    i.putExtra(DashboardReader.QTY_PHOTOS,         dashboard.qtyPhotos);
                    i.putExtra(DashboardReader.QTY_VIDEOS,         dashboard.qtyVideos);
                    i.putExtra(DashboardReader.QTY_JOURNAL,        dashboard.qtyJournal);
//                    if(gp == 1) cp += 2;
                    i.putExtra(DashboardReader.INITIAL, cp + factor);
                    
                    startActivityForResult(i, 0);
                    break;
                } default:
                    break;
            }
        } else if(gp == 2) {
            switch ((int)id) {
                case QTY_NON_SHARING_IMAGES: {
                    Intent i = new Intent(this, ImageGallerySharingContainer.class);
                    i.putExtra(ImageGallerySharingContainer.INITIAL_TAB, 2);
                    startActivity(i);
                    break;
                }
                case QTY_NON_SHARING_VIDEOS: {
                    Intent i = new Intent(this, VideoGallerySharingContainer.class);
                    i.putExtra(VideoGallerySharingContainer.INITIAL_TAB, 2);
                    startActivity(i);
                    break;
                }
            }
        }
        
        return super.onChildClick(parent, v, gp, cp, id);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, 0, 0, "Refresh").setIcon(R.drawable.ic_menu_refresh);
        menu.add(1, 1, 1, "Preferences").setIcon(android.R.drawable.ic_menu_preferences);
        menu.add(2, 2, 2, "Info").setIcon(android.R.drawable.ic_menu_info_details);
        return super.onCreateOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 0: {//refresh
                task = new RefreshTask().execute(this);
                return true;
            }
            case 1: {//preferences
                PreferencesActivity.show(this);
                return true;
            }
            case 2: {//info
                EulaLicenseAgreement.showEula(this, false);
                return true;
            }
        }
        return false;
    }
    
    class CleanSyncInfo extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            ContentResolver cr = getContentResolver();
            Cursor c = cr.query(Sync.CONTENT_URI, null, null, null, Sync._ID + " DESC");
            try {
                if(c != null && c.moveToFirst()) {
                    if(c.getCount() > 5) {
                        int id = c.getInt(c.getColumnIndexOrThrow(Sync._ID));
                        id -= 5;
                        
                        cr.delete(Sync.CONTENT_URI, Sync._ID + " < " + id, null);
                        
                        publishProgress();
                    }
                }
            } finally {
                CloseableUtil.safeClose(c);
                c = null;
            }
            
            return null;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
            m_adapter.notifyDataSetChanged();
        }
    }
    
    private class RefreshTask extends DashboardUpdaterTask {
        private View emptyView;
        @Override
        public void onPreExecute() {
            getParent().setProgressBarIndeterminateVisibility(true);
            setListAdapter(null);
            
            emptyView = (View)findViewById(android.R.id.empty);
//            if(emptyView instanceof ViewStub) {
//                emptyView = ((ViewStub)emptyView).inflate();
//            }
            emptyText = (TextView)emptyView.findViewById(android.R.id.text1);
            emptyPG = (ProgressBar)emptyView.findViewById(android.R.id.progress);
            
            emptyText.setText("Refreshing your dashboard\nPlease wait...");
            emptyPG.setVisibility(View.VISIBLE);
        }
        
        @Override
        public void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            getParent().setProgressBarIndeterminateVisibility(false);
            
            emptyView.setVisibility(View.GONE);
            buildDashboard();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) {
            task.cancel(true);
        }
        
        dashboard = null;
        emptyText = null;
        emptyPG = null;
        task = null;
    }
}
